package com.jackiepenghe.rangedatepickerlibrary

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.IntDef
import androidx.annotation.IntRange
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jackiepenghe.rangedatepickerlibrary.listener.OnDateSelectChangedListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale


/**
 * 范围日期选择器
 *
 * @author jackie
 */
@Suppress("unused")
class RangeDatePickerView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : RelativeLayout(
    context,
    attrs,
    defStyleAttr,
    defStyleRes
) {

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 静态声明
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    companion object {
        private const val MAX_SELECT_COUNT = 28
        private val ACTIVE_DATE_FORMAT = SimpleDateFormat("yyyy/MM/dd", Locale.CHINA)

    }

    object SelectMode {
        /**
         * 独立选择（每次选择都作为新的起始与结束）
         */
        const val INDEPENDENT = 1

        /**
         * 连续选择（在选择的基础上额外增加更多的选择项）
         */
        const val CONTINUOUS = 2

        /**
         * 单选模式
         */
        const val SINGLE_SELECT = 3
    }


    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 接口定义
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    @IntDef(VISIBLE, INVISIBLE, GONE)
    @Retention(AnnotationRetention.SOURCE)
    annotation class Visibility

    @IntDef(SelectMode.INDEPENDENT, SelectMode.CONTINUOUS)
    @Retention(AnnotationRetention.SOURCE)
    annotation class ISelectMode

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 属性声明
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /* * * * * * * * * * * * * * * * * * * 常量 * * * * * * * * * * * * * * * * * * */

    private val defaultTextSize: Float

    private val dataRecyclerViewAdapter = DataRecyclerViewAdapter()

    private val rootView: View

    /* * * * * * * * * * * * * * * * * * * View * * * * * * * * * * * * * * * * * * */

    /**
     * 默认的TextView
     */
    private lateinit var defaultTextView: TextView

    /**
     * 顶部 周日
     */
    private lateinit var sundayTv: TextView

    /**
     * 顶部 周一
     */
    private lateinit var mondayTv: TextView

    /**
     * 顶部 周二
     */
    private lateinit var tuesDayTv: TextView

    /**
     * 顶部 周三
     */
    private lateinit var wednesdayTv: TextView

    /**
     * 顶部 周四
     */
    private lateinit var thursdayTv: TextView

    /**
     * 顶部 周五
     */
    private lateinit var fridayTv: TextView

    /**
     * 顶部 周六
     */
    private lateinit var saturdayTv: TextView

    /**
     * 分割线
     */
    private lateinit var dividingLineView: View

    /**
     * 展示要选择的日期的RecyclerView
     */
    private lateinit var dateSelectRecyclerView: RecyclerView

    /* * * * * * * * * * * * * * * * * * * attrs * * * * * * * * * * * * * * * * * * */

    /**
     * 全局文本大小
     */
    private var globalTextSize: Float = 0f


    /**
     * 背景色
     */
    private var backgroundDrawable: Drawable? = null

    /**
     * 顶部 周文本大小
     */
    private var weekTextSize: Float = 0f

    /**
     * 顶部 周 周末文本颜色
     */
    @ColorInt
    private var weekendTextColor: Int = 0

    /**
     * 顶部 周 非周末文本颜色
     */
    @ColorInt
    private var notWeekendTextColor: Int = 0

    /**
     * 分割线颜色
     */
    private var dividingLineBackground: Drawable? = null

    /**
     *  分割线的高度
     */
    private var dividingLineHeight: Float = 0f

    /**
     * 分割线是否显示
     */
    private var dividingLineVisible: Int = VISIBLE

    /**
     * 分割线topMargin 优先级 高于 dividingLineMargin
     */
    private var dividingLineTopMargin: Float = 0f

    /**
     * 分割线bottomMargin 优先级 高于 dividingLineMargin
     */
    private var dividingLineBottomMargin: Float = 0f

    /**
     * 日期选择界面中，显示 月份信息 的文本的文字大小
     */
    private var dateMonthTextSize: Float = 0f

    /**
     * 日期选择界面中，显示 月份信息 的文本的文字颜色
     */
    @ColorInt
    private var dateMonthTextColor: Int = 0

    /**
     * 日期选项的大小
     */
    private var dateItemSize: Float = 0f

    /**
     * 日期选项的item 正常的背景
     */
    private var dateItemBackgroundNormal: Drawable? = null

    /**
     * 日期选项的item 空白文本的背景
     */
    private var dateItemBackgroundEmpty: Drawable? = null

    /**
     * 日期选项的item 选中的背景
     */
    private var dateItemBackgroundSelect: Drawable? = null

    /**
     * 日期选项的item 选中的日期为起始日期时的背景
     */
    private var dateItemBackgroundStart: Drawable? = null

    /**
     * 日期选项的item 选中的日期为结束日期时的背景
     */
    private var dateItemBackgroundEnd: Drawable? = null

    /**
     * 日期选项的item 选中的日期为未激活(不可选)时的背景
     */
    private var dateItemBackgroundDisable: Drawable? = null

    /**
     * 单选中一个日期时，日期的背景（不设置时，默认与dateItemBackgroundSelect一致）
     */
    private var dateItemBackgroundSingleSelect: Drawable? = null

    /**
     * 日期选项的item 文本大小
     */
    private var dateItemTextSize = 0f

    /**
     * 日期选项的item 正常文本颜色
     */
    @ColorInt
    private var dateItemTextColorNormal = 0

    /**
     * 日期选项的item 选中文本颜色
     */
    private var dateItemTextColorSelect = 0

    /**
     * 日期选项的item 未激活(不可选)时文本颜色
     */
    private var dateItemTextColorDisable = 0

    /**
     * 是否允许选择激活日期之前的日期
     */
    private var allowSelectBeforeActiveDate = false

    /**
     * 是否显示上月份的日期选择器
     */
    private var showLastMonthDate = false

    /**
     * 最大可选的日期数量
     */
    private var dateMaxSelectCount = MAX_SELECT_COUNT

    /**
     * 不可用状态的日期
     */
    private var activeDate: Date = dataRecyclerViewAdapter.dateActiveDate

    /**
     * 显示月份信息的文本格式
     */
    private var dateMonthFormat: String? = null

    /**
     * 选择模式
     */
    private var selectMode = SelectMode.INDEPENDENT


    /* * * * * * * * * * * * * * * * * * * 可空属性 * * * * * * * * * * * * * * * * * * */

    private var onDateSelectChangedListener: OnDateSelectChangedListener? = null

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 构造方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    init {
        rootView = inflate(
            context,
            R.layout.com_jackiepenghe_rangedatepickerlibrary_view_range_date_picker,
            null
        )
        addView(rootView)
        val layoutParams = rootView.layoutParams as LayoutParams
        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
        layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
        rootView.layoutParams = layoutParams
        initViews()
        defaultTextSize = defaultTextView.textSize
        initAttrValue(attrs)
        attachAttrToView()
        initViewData()
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 重写方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    override fun setBackgroundColor(color: Int) {
        background = ColorDrawable(color)
    }

    override fun setBackgroundResource(resid: Int) {
        background = ContextCompat.getDrawable(context, resid)
    }

    override fun setBackground(background: Drawable?) {
        backgroundDrawable = background
        attachRootViewBackGound()
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 公开方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 设置全局文本大小
     * 设置此选项会覆盖其他文本大小
     * 如需要分设置其他文本大小，请先启用此方法后，再调用后其他设置文本大小的方法
     */
    fun setGlobalTextSize(textSize: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP) {
        globalTextSize =
            TypedValue.applyDimension(unit, textSize, resources.displayMetrics)
        this.weekTextSize = globalTextSize
        this.dateMonthTextSize = globalTextSize
        this.dateItemTextSize = globalTextSize
        attachWeekTextSize()
        attachWeekTextColor()
        refreshDateItemParams()
    }

    /**
     * 设置周文本大小
     */
    fun setWeekTextSize(textSize: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP) {
        weekTextSize = TypedValue.applyDimension(unit, textSize, resources.displayMetrics)
        attachWeekTextSize()
    }

    /**
     * 设置周末文本颜色
     */
    fun setWeekendTextColor(@ColorInt color: Int) {
        weekendTextColor = color
        attachWeekTextColor()
    }

    /**
     * 设置周末文本颜色
     */
    fun setWeekendTextColorRes(@ColorRes color: Int) {
        setWeekendTextColor(ContextCompat.getColor(context, color))
    }

    /**
     * 设置非周末文本颜色
     */
    fun setNotWeekendTextColor(@ColorInt color: Int) {
        notWeekendTextColor = color
        attachWeekTextColor()
    }

    /**
     * 设置非周末文本颜色
     */
    fun setNotWeekendTextColorRes(@ColorRes color: Int) {
        setNotWeekendTextColor(ContextCompat.getColor(context, color))
    }

    /**
     * 设置分割线背景色
     */
    fun setDividingLineBackground(background: Drawable?) {
        dividingLineBackground = background
        attachDividingLineBackground()
    }

    /**
     * 设置分割线背景色
     */
    fun setDividingLineBackgroundColor(color: Int) {
        setDividingLineBackground(ColorDrawable(color))
    }

    /**
     * 设置分割线背景色
     */
    fun setDividingLineBackgroundResource(resid: Int) {
        setDividingLineBackground(ContextCompat.getDrawable(context, resid))
    }

    /**
     * 设置分割线高度（像素）
     */
    fun setDividingLineHeight(height: Float) {
        dividingLineHeight = height
        attachDividingLineLayoutParams()
    }

    /**
     * 设置是否显示分割线
     */
    fun setDividingLineVisible(@Visibility visible: Int) {
        dividingLineVisible = visible
        attachDividingLineVisibility()
    }

    /**
     * 设置分割线的margin
     */
    fun setDividingLineMargin(topMargin: Float, bottomMargin: Float) {
        dividingLineTopMargin = topMargin
        dividingLineBottomMargin = bottomMargin
        attachDividingLineLayoutParams()
    }

    /**
     * 设置显示 月份信息 的文本的大小
     */
    fun setDateMonthTextSize(textSize: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP) {
        dateMonthTextSize = TypedValue.applyDimension(unit, textSize, resources.displayMetrics)
        refreshDateItemParams()
    }

    /**
     * 设置显示 月份信息 的文本的颜色
     */
    fun setDateMonthTextColor(color: Int) {
        dateMonthTextColor = color
        refreshDateItemParams()
    }

    /**
     * 设置日期选项的大小
     */
    fun setDateItemSize(itemSize: Float) {
        dateItemSize = itemSize
        refreshDateItemParams()
    }

    /**
     * 设置日期选项正常的背景色
     */
    fun setDateItemBackgroundNormal(background: Drawable?) {
        dateItemBackgroundNormal = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项正常的背景色
     */
    fun setDateItemBackgroundNormalColor(@ColorInt color: Int) {
        setDateItemBackgroundNormal(ColorDrawable(color))
    }

    /**
     * 设置日期选项正常的背景色
     */
    fun setDateItemBackgroundNormalRes(@DrawableRes resId: Int) {
        setDateItemBackgroundNormal(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项选中的背景色
     */
    fun setDateItemBackgroundSelect(background: Drawable?) {
        dateItemBackgroundSelect = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项选中的背景色
     */
    fun setDateItemBackgroundSelectColor(@ColorInt color: Int) {
        setDateItemBackgroundSelect(ColorDrawable(color))
    }

    /**
     * 设置日期选项选中的背景色
     */
    fun setDateItemBackgroundSelectRes(@DrawableRes resId: Int) {
        setDateItemBackgroundSelect(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项选中的背景色(单选中时)
     */
    fun setDateItemBackgroundSingleSelect(background: Drawable?) {
        dateItemBackgroundSingleSelect = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项选中的背景色(单选中时)
     */
    fun setDateItemBackgroundSingleSelectColor(@ColorInt color: Int) {
        setDateItemBackgroundSingleSelect(ColorDrawable(color))
    }

    /**
     * 设置日期选项选中的背景色(单选中时)
     */
    fun setDateItemBackgroundSingleSelectRes(@DrawableRes resId: Int) {
        setDateItemBackgroundSingleSelect(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项起始日期的背景色
     */
    fun setDateItemBackgroundStart(background: Drawable?) {
        dateItemBackgroundStart = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项起始日期的背景色
     */
    fun setDateItemBackgroundStartColor(@ColorInt color: Int) {
        setDateItemBackgroundStart(ColorDrawable(color))
    }

    /**
     * 设置日期选项起始日期的背景色
     */
    fun setDateItemBackgroundStartRes(@DrawableRes resId: Int) {
        setDateItemBackgroundStart(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项结束日期的背景色
     */
    fun setDateItemBackgroundEnd(background: Drawable?) {
        dateItemBackgroundEnd = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项结束日期的背景色
     */
    fun setDateItemBackgroundEndColor(@ColorInt color: Int) {
        setDateItemBackgroundEnd(ColorDrawable(color))
    }

    /**
     * 设置日期选项结束日期的背景色
     */
    fun setDateItemBackgroundEndRes(@DrawableRes resId: Int) {
        setDateItemBackgroundEnd(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项未激活(不可选)的背景色
     */
    fun setDateItemBackgroundDisable(background: Drawable?) {
        dateItemBackgroundDisable = background
        refreshDateItemParams()
    }

    /**
     * 设置日期选项未激活(不可选)的背景色
     */
    fun setDateItemBackgroundDisableColor(@ColorInt color: Int) {
        setDateItemBackgroundDisable(ColorDrawable(color))
    }

    /**
     * 设置日期选项未激活(不可选)的背景色
     */
    fun setDateItemBackgroundDisableRes(@DrawableRes resId: Int) {
        setDateItemBackgroundDisable(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置日期选项 文本的大小
     */
    fun setDateItemTextSize(textSize: Float, unit: Int = TypedValue.COMPLEX_UNIT_DIP) {
        dateItemTextSize = TypedValue.applyDimension(unit, textSize, resources.displayMetrics)
        refreshDateItemParams()
    }

    /**
     * 设置日期选项 正常的文本颜色
     */
    fun setDateItemTextColorNormal(@ColorInt color: Int) {
        dateItemTextColorNormal = color
        refreshDateItemParams()
    }

    /**
     * 设置日期选项 正常的文本颜色
     */
    fun setDateItemTextColorNormalRes(@ColorRes resId: Int) {
        setDateItemTextColorNormal(ContextCompat.getColor(context, resId))
    }

    /**
     * 设置日期选项 选中的文本颜色
     */
    fun setDateItemTextColorSelect(@ColorInt color: Int) {
        dateItemTextColorSelect = color
        refreshDateItemParams()
    }

    /**
     * 设置日期选项 选中的文本颜色
     */
    fun setDateItemTextColorSelectRes(@ColorRes resId: Int) {
        setDateItemTextColorSelect(ContextCompat.getColor(context, resId))
    }

    /**
     * 设置日期选项 选中的文本颜色
     */
    fun setDateItemTextColorDisable(@ColorInt color: Int) {
        dateItemTextColorDisable = color
        refreshDateItemParams()
    }

    /**
     * 设置日期选项 选中的文本颜色
     */
    fun setDateItemTextColorDisableRes(@ColorRes resId: Int) {
        setDateItemTextColorDisable(ContextCompat.getColor(context, resId))
    }

    /**
     * 设置 是否允许选择激活日期之前的日期
     */
    fun setAllowSelectBeforeActiveDate(allow: Boolean) {
        allowSelectBeforeActiveDate = allow
        refreshDateItemParams()
    }

    /**
     * 设置 选择日期的最大天数
     */
    fun setDateMaxSelectCount(@IntRange(from = 0, to = MAX_SELECT_COUNT.toLong()) count: Int) {
        dateMaxSelectCount = count
        refreshDateItemParams()
    }

    /**
     * 设置 显示 月份信息的日期格式化规则
     */
    fun setDateMonthFormat(format: String) {
        dateMonthFormat = format
        refreshDateItemParams()
    }

    /**
     * 设置 激活日期
     */
    fun setActiveDate(date: Date) {
        activeDate = date.keepDateOnly()
        refreshDateItemParams()
    }

    /**
     * 设置 是否显示上月日期
     */
    fun setShowLastMonthDate(show: Boolean) {
        showLastMonthDate = show
        refreshDateItemParams()
    }

    /**
     * 设置默认的选中日期
     */
    @SuppressLint("NotifyDataSetChanged")
    fun setSelectDate(startDate: Date?, endDate: Date? = null) {
        if (startDate == null) {
            dataRecyclerViewAdapter.startDate = null
            dataRecyclerViewAdapter.endDate = null
        } else {
            val start = startDate.keepDateOnly()
            if (endDate == null) {
                dataRecyclerViewAdapter.startDate = start
                dataRecyclerViewAdapter.endDate = null
            } else {
                val end = endDate.keepDateOnly()
                if (start.after(end) || start == end) {
                    throw RuntimeException("结束日期必须大于起始日期")
                }
                if (start.differDay(end) > dateMaxSelectCount) {
                    throw RuntimeException("日期之间超过最大可选日期")
                }
                if (!allowSelectBeforeActiveDate) {
                    if (start.before(dataRecyclerViewAdapter.dateActiveDate)) {
                        throw RuntimeException("起始日期不能早于激活日期")
                    }
                }
                dataRecyclerViewAdapter.startDate = start
                dataRecyclerViewAdapter.endDate = end
            }
        }
        dataRecyclerViewAdapter.notifyDataSetChanged()
        dataRecyclerViewAdapter.refreshDateListener()
    }

    /**
     * 设置空白字符日期的背景色
     */
    fun setDateItemBackgroundEmpty(drawable: Drawable?) {
        dateItemBackgroundEmpty = drawable
        refreshDateItemParams()
    }

    /**
     * 设置空白字符日期的背景色
     */
    fun setDateItemBackgroundEmptyColor(@ColorInt color: Int) {
        setDateItemBackgroundEmpty(ColorDrawable(color))
    }

    /**
     * 设置空白字符日期的背景色
     */
    fun setDateItemBackgroundEmptyRes(@DrawableRes resId: Int) {
        setDateItemBackgroundEmpty(ContextCompat.getDrawable(context, resId))
    }

    /**
     * 设置选择模式
     */
    fun setSelectMode(@ISelectMode selectMode: Int) {
        this.selectMode = selectMode
        refreshDateItemParams()
    }

    /**
     * 设置回调
     */
    fun setOnDateSelectChangedListener(onDateSelectChangedListener: OnDateSelectChangedListener?) {
        this.onDateSelectChangedListener = onDateSelectChangedListener
        dataRecyclerViewAdapter.setOnDateSelectChangedListener(onDateSelectChangedListener)
    }

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
     *
     * 私有方法
     *
     * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    /**
     * 初始化View
     */
    private fun initViews() {
        //顶部 周
        defaultTextView =
            findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_default_text_view)
        sundayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_sunday_tv)
        mondayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_monday_tv)
        tuesDayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_tuesday_tv)
        wednesdayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_wednesday_tv)
        thursdayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_thursday_tv)
        fridayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_friday_tv)
        saturdayTv = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_saturday_tv)
        //分割线
        dividingLineView = findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_dividing_line)
        //展示要选择的日期的RecyclerView
        dateSelectRecyclerView =
            findViewById(R.id.com_jackiepenghe_rangedatepickerlibrary_recycler_view)
    }

    /**
     * 初始化自定义属性中的数据
     */
    private fun initAttrValue(attrs: AttributeSet?) {
        val obtainStyledAttributes =
            context.obtainStyledAttributes(attrs, R.styleable.RangeDatePickerView)
        //背景色
        backgroundDrawable = obtainStyledAttributes.getDrawable(
            R.styleable.RangeDatePickerView_android_background
        )
        //全局文本大小，没有就使用默认值
        globalTextSize = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_globalTextSize,
            defaultTextSize
        )
        //周 文本大小，没有就使用全局文本大小
        weekTextSize = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_weekTextSize,
            globalTextSize
        )
        //非周末 文本颜色，没有就使用默认颜色
        notWeekendTextColor = obtainStyledAttributes.getColor(
            R.styleable.RangeDatePickerView_notWeekendTextColor,
            ContextCompat.getColor(
                context,
                R.color.com_jackiepenghe_rangedatepickerlibrary_default_not_weekend_color
            )
        )
        //周末 文本颜色，没有就使用默认颜色
        weekendTextColor = obtainStyledAttributes.getColor(
            R.styleable.RangeDatePickerView_weekendTextColor,
            ContextCompat.getColor(
                context,
                R.color.com_jackiepenghe_rangedatepickerlibrary_default_weekend_color
            )
        )
        //分割线颜色
        dividingLineBackground =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dividingLineBackground)
        //分割线高度
        dividingLineHeight = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dividingLineHeight,
            dpToPx(1f)
        )
        //分割线是否显示
        val dividingLineVisibleEnum = obtainStyledAttributes.getInt(
            R.styleable.RangeDatePickerView_dividingLineVisible,
            0
        )
        when (dividingLineVisibleEnum) {
            0 -> {
                dividingLineVisible = VISIBLE
            }

            1 -> {
                dividingLineVisible = INVISIBLE
            }

            2 -> {
                dividingLineVisible = GONE
            }
        }
        //分割线margin
        val dividingLineMargin = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dividingLineMargin,
            dpToPx(0f)
        )
        //分割线topMargin
        dividingLineTopMargin = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dividingLineTopMargin,
            dividingLineMargin
        )
        //分割线bottomMargin
        dividingLineBottomMargin = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dividingLineBottomMargin,
            dividingLineMargin
        )
        dateMonthTextSize = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dateMonthTextSize,
            globalTextSize
        )
        dateMonthTextColor = obtainStyledAttributes.getColor(
            R.styleable.RangeDatePickerView_dateMonthTextColor,
            ContextCompat.getColor(
                context,
                R.color.com_jackiepenghe_rangedatepickerlibrary_default_date_month_text_color
            )
        )
        dateItemSize = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dateItemSize,
            0f
        )
        dateItemBackgroundNormal =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundNormal)

        dateItemBackgroundSelect =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundSelect)

        dateItemBackgroundEmpty =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundEmpty)

        dateItemTextSize = obtainStyledAttributes.getDimension(
            R.styleable.RangeDatePickerView_dateItemTextSize,
            globalTextSize
        )
        dateItemTextColorNormal =
            obtainStyledAttributes.getColor(
                R.styleable.RangeDatePickerView_dateItemTextColorNormal,
                ContextCompat.getColor(
                    context,
                    R.color.com_jackiepenghe_rangedatepickerlibrary_default_date_item_text_color_normal
                )
            )
        dateItemTextColorSelect =
            obtainStyledAttributes.getColor(
                R.styleable.RangeDatePickerView_dateItemTextColorSelect,
                ContextCompat.getColor(
                    context,
                    R.color.com_jackiepenghe_rangedatepickerlibrary_default_date_item_text_color_select
                )
            )
        dateItemTextColorDisable =
            obtainStyledAttributes.getColor(
                R.styleable.RangeDatePickerView_dateItemTextColorDisable,
                ContextCompat.getColor(
                    context,
                    R.color.com_jackiepenghe_rangedatepickerlibrary_default_date_item_text_color_disable
                )
            )
        dateItemBackgroundStart =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundStart)
        dateItemBackgroundEnd =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundEnd)
        dateItemBackgroundDisable =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundDisable)
        dateItemBackgroundSingleSelect =
            obtainStyledAttributes.getDrawable(R.styleable.RangeDatePickerView_dateItemBackgroundSingleSelect)
        if (dateItemBackgroundSingleSelect == null) {
            dateItemBackgroundSingleSelect = dateItemBackgroundSelect
        }
        allowSelectBeforeActiveDate = obtainStyledAttributes.getBoolean(
            R.styleable.RangeDatePickerView_allowSelectBeforeActiveDate,
            false
        )
        dateMonthFormat =
            obtainStyledAttributes.getString(R.styleable.RangeDatePickerView_dateMonthFormat)
        dateMaxSelectCount =
            obtainStyledAttributes.getInt(
                R.styleable.RangeDatePickerView_dateMaxSelectCount,
                MAX_SELECT_COUNT
            )
        if (dateMaxSelectCount < 0 || dateMaxSelectCount > MAX_SELECT_COUNT) {
            dateMaxSelectCount = MAX_SELECT_COUNT
        }
        showLastMonthDate =
            obtainStyledAttributes.getBoolean(
                R.styleable.RangeDatePickerView_showLastMonthDate,
                false
            )
        val activeDateString =
            obtainStyledAttributes.getString(R.styleable.RangeDatePickerView_activeDate)
        activeDate = if (activeDateString == null) {
            dataRecyclerViewAdapter.dateActiveDate
        } else {
            try {
                ACTIVE_DATE_FORMAT.parse(activeDateString) ?: dataRecyclerViewAdapter.dateActiveDate
            } catch (e: Exception) {
                dataRecyclerViewAdapter.dateActiveDate
            }
        }
        selectMode = obtainStyledAttributes.getInt(
            R.styleable.RangeDatePickerView_selectMode,
            SelectMode.INDEPENDENT
        )
        obtainStyledAttributes.recycle()
    }

    /**
     * 将自定义属性应用到View中
     */
    private fun attachAttrToView() {
        attachRootViewBackGound()
        attachWeekTextSize()
        attachWeekTextColor()
        attachDividingLineAttrs()
    }

    private fun attachRootViewBackGound() {
        if (backgroundDrawable != null) {
            rootView.background = backgroundDrawable
        } else {
            rootView.setBackgroundColor(
                ContextCompat.getColor(
                    context,
                    R.color.com_jackiepenghe_rangedatepickerlibrary_default_range_date_background_color
                )
            )
        }
    }

    /**
     * 应用周文本大小
     */
    private fun attachWeekTextSize() {
        sundayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        mondayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        tuesDayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        wednesdayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        thursdayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        fridayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
        saturdayTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, weekTextSize)
    }

    /**
     * 应用周文本颜色
     */
    private fun attachWeekTextColor() {
        sundayTv.setTextColor(weekendTextColor)
        mondayTv.setTextColor(notWeekendTextColor)
        tuesDayTv.setTextColor(notWeekendTextColor)
        wednesdayTv.setTextColor(notWeekendTextColor)
        thursdayTv.setTextColor(notWeekendTextColor)
        fridayTv.setTextColor(notWeekendTextColor)
        saturdayTv.setTextColor(weekendTextColor)
    }

    private fun attachDividingLineAttrs() {
        attachDividingLineLayoutParams()
        attachDividingLineBackground()
        attachDividingLineVisibility()
    }

    private fun attachDividingLineVisibility() {
        dividingLineView.visibility = dividingLineVisible
    }

    private fun attachDividingLineBackground() {
        if (dividingLineBackground != null) {
            dividingLineView.background = dividingLineBackground
        } else {
            dividingLineView.setBackgroundColor(
                ContextCompat.getColor(
                    context,
                    R.color.com_jackiepenghe_rangedatepickerlibrary_default_dividing_line_color
                )
            )
        }
    }

    private fun attachDividingLineLayoutParams() {
        val layoutParams = dividingLineView.layoutParams as LinearLayout.LayoutParams
        layoutParams.height = (dividingLineHeight + 0.5).toInt()
        layoutParams.topMargin = (dividingLineTopMargin + 0.5).toInt()
        layoutParams.bottomMargin = (dividingLineBottomMargin + 0.5).toInt()
        dividingLineView.layoutParams = layoutParams
    }

    /**
     * 转换DP值为象素值
     *
     * @param dpValue DP值
     * @return 象素值
     */
    private fun dpToPx(dpValue: Float): Float {
        return Resources.getSystem().displayMetrics.density * dpValue
    }

    /**
     * 初始化View数据
     */
    private fun initViewData() {
        dateSelectRecyclerView.layoutManager = LinearLayoutManager(context)
        dateSelectRecyclerView.adapter = dataRecyclerViewAdapter
        refreshDateItemParams()
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun refreshDateItemParams() {
        dataRecyclerViewAdapter.setDateMonthTextSize(dateMonthTextSize)
        dataRecyclerViewAdapter.setDateMonthTextColor(dateMonthTextColor)
        dataRecyclerViewAdapter.setDateItemSize(dateItemSize)
        dataRecyclerViewAdapter.setDateItemBackgroundNormal(dateItemBackgroundNormal)
        dataRecyclerViewAdapter.setDateItemBackgroundSelect(dateItemBackgroundSelect)
        dataRecyclerViewAdapter.setDateItemTextSize(dateItemTextSize)
        dataRecyclerViewAdapter.setDateItemTextColorNormal(dateItemTextColorNormal)
        dataRecyclerViewAdapter.setDateItemTextColorSelect(dateItemTextColorSelect)
        dataRecyclerViewAdapter.setDateItemTextColorDisable(dateItemTextColorDisable)
        dataRecyclerViewAdapter.setDateItemBackgroundStart(dateItemBackgroundStart)
        dataRecyclerViewAdapter.setDateItemBackgroundEnd(dateItemBackgroundEnd)
        dataRecyclerViewAdapter.setDateItemBackgroundDisable(dateItemBackgroundDisable)
        dataRecyclerViewAdapter.setDateItemBackgroundEmpty(dateItemBackgroundEmpty)
        dataRecyclerViewAdapter.setDateItemBackgroundSingleSelect(dateItemBackgroundSingleSelect)
        dataRecyclerViewAdapter.setAllowSelectBeforeActiveDate(allowSelectBeforeActiveDate)
        dataRecyclerViewAdapter.setDateMonthFormat(dateMonthFormat)
        dataRecyclerViewAdapter.setDateMaxSelectCount(dateMaxSelectCount)
        dataRecyclerViewAdapter.setShowLastMonthDate(showLastMonthDate)
        dataRecyclerViewAdapter.setActiveDate(activeDate)
        dataRecyclerViewAdapter.setSelectMode(selectMode)
        dataRecyclerViewAdapter.setOnDateSelectChangedListener(onDateSelectChangedListener)
        dataRecyclerViewAdapter.notifyDataSetChanged()
    }
}
